package com.leunpha.mini.spider;


import com.leunpha.mini.net.MiniRequest;
import com.leunpha.mini.net.Request;
import com.leunpha.mini.net.events.NetEvent;
import com.leunpha.mini.net.events.NetState;
import com.leunpha.mini.net.listener.Listener;
import com.leunpha.mini.net.listener.ServerListener;
import com.leunpha.mini.spider.annotation.Regex;
import com.leunpha.mini.spider.bean.AbstractBean;
import com.leunpha.mini.spider.bean.ErrorBean;
import com.leunpha.mini.spider.listener.SpiderListener;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Observer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * User: zhoujingjie
 * Date: 14-6-24
 * Time: 上午9:05
 */
public class Spider extends ServerListener {

    /**
     * 匹配内容
     * @param reg
     * @param content
     * @param multi        //多匹配
     * @param splitor
     * @return
     */
    private String matcherContent(String reg,String content,boolean multi,String splitor){
        Matcher matcher = Pattern.compile(reg).matcher(content);
        if(multi){
            StringBuilder sb =new StringBuilder(content.length());
            while (matcher.find()){
                sb.append(matcher.group(1));
                sb.append(splitor);
            }
            return sb.toString();
        }else{
            if(matcher.find()){
                return matcher.group(1);
            }
        }
        return null;
    }

    private String matcherContent(String reg,String content){
        return matcherContent(reg,content,false,"");
    }


    /**
     * 运行
     * @param url
     * @param cls
     * @param <T>
     * @return
     */
    public <T extends AbstractBean> T run(final String url,Class<T> cls){
        T t = null;
        try {
            notifyListener(NetEvent.instance(NetState.BEGIN, url));
            t = cls.newInstance();
            t.docURL = url;
            Request request = new MiniRequest(url);
            request.execute();
            String result = request.getResponseByAsString();
            for(Field field: cls.getFields()){
                String temp = result;
                Regex regex = field.getAnnotation(Regex.class);
                if(regex != null){
                    if(regex.multiple()){
                        String []regs =regex.value().split(regex.splitor());
                        for(int i=0;i<regs.length;i++){
                            temp = matcherContent(regs[i],temp,i == regs.length-1,regex.splitor());
                        }
                    }else{
                        temp = matcherContent(regex.value(),temp);
                    }
                    try {
                        field.set(t,temp);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            notifyListener(NetEvent.instance(NetState.SUCCESS, t));
            return t;
        } catch (final Exception e) {
            notifyListener(NetEvent.instance(NetState.ERROR, new ErrorBean(e,url)));
            e.printStackTrace();
        }finally {
            notifyListener(NetEvent.instance(NetState.END, t));
        }
        return null;
    }


    @Override
    public synchronized void addObserver(Observer o) {
        throw new UnsupportedOperationException("不支持此操作");
    }

    public synchronized void addListener(Listener listener){
        super.addObserver(listener);
    }


}
